/* advrp.h
 *
 *    Copyright 2010 Patrick Allen
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
*/

#ifndef ADVRP_ADVRP_H
#define ADVRP_ADVRP_H

#define DEFAULT_UPDATE_TIMER 10
#define DEFAULT_INVALID_TIMER 30
#define DEFAULT_HOLDDOWN_TIMER 60
#define MAX_UPDATE_TIMER 300
#define MAX_INVALID_TIMER 900
#define MAX_HOLDDOWN_TIMER 1800
#define ON 1
#define OFF 0
#define ADVRP_VERSION 0        // Packet structure version
#define RECORDS_IN_UPDATE 10
#define SPLIT_HORIZON 1
#define MAX_METRIC 15          // 16 is "infinity"
#define ADVRP_PORT 2771        // 0xAD3
#define RT_TABLE_ADVRP 27
#define THREAD_COUNT 4
#define LOOPBACK_IP 16777343   // 127.0.0.1

#define PIDFILE "/var/run/advrp.pid"

/* route commands used by kernel_route() function: */
#define ADD 0
#define DEL 1
#define MOD 2

#include <sys/types.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <net/if.h>

typedef struct interface {
	char ifname[IFNAMSIZ];
	uint8_t ifnumber;
	_Bool active;                // Send updates on this interface?
	in_addr_t network;
	in_addr_t mask;
	in_addr_t ip;
	in_addr_t broadcast;
	struct interface * next;
	struct interface * prev;
} interface;

typedef struct internalRoute {
	struct neighbor * neigh;
	struct neighborRoute * route;
	struct internalRoute * next;
	struct internalRoute * prev;
} internalRoute;

#pragma pack(1)
typedef struct updateRecord {
	in_addr_t network;
	uint8_t preflen;
	uint8_t metric;
} updateRecord;

typedef struct updateMessage {
	int version;
	int nrec;
	struct updateRecord updateRecord[RECORDS_IN_UPDATE];
} updateMessage;
#pragma pack(0)

typedef struct neighbor {
	in_addr_t addr;
	char ipstr[INET_ADDRSTRLEN];
	uint8_t distance;
	time_t lastheard;
	struct interface * iface;
	struct neighborRoute * firstroute;
	struct neighbor * next;
	struct neighbor * prev;
} neighbor;

typedef struct neighborRoute {
	in_addr_t network;
	char netstr[INET_ADDRSTRLEN];
	uint8_t preflen;
	uint64_t hash;
	uint8_t metric;                // Distance from local router
	_Bool installed;               // Currently installed in routing table
	_Bool valid;
	struct neighborRoute * next;
	struct neighborRoute * prev;
} neighborRoute;

typedef struct hdNetwork {              // Networks on holddown
	uint64_t hash;
	time_t timer;
	struct hdNetwork * prev;
	struct hdNetwork * next;
} hdNetwork;

#endif
